import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.JLabel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.border.LineBorder;
import java.awt.Color;
import javax.swing.JComboBox;
import javax.swing.JRadioButton;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;

public class MainFrame extends JFrame {

	private JPanel contentPane;
	private JTextArea textShow;
	private JPanel panelOption;
	private JComboBox<Object> comboBox;

	private JPanel panelNew;
	private JTextArea textArea_New;
	private JRadioButton rdbtnLinkStack;
	private JRadioButton rdbtnSequentialStack;
	private JTextField textSize_New;

	private JPanel panelPush;
	private JTextField textValue_Push;
	private JLabel labelResult_Push;

	private JPanel panelShow;
	private JLabel labelMessage_Show;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MainFrame frame = new MainFrame();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public MainFrame() {
		setTitle("Stack");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 551, 435);
		contentPane = new JPanel();
		setContentPane(contentPane);
		contentPane.setLayout(null);

		JButton btnNew = new JButton("New");
		btnNew.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				switchPanel("New");
			}
		});
		btnNew.setBounds(391, 24, 113, 27);
		contentPane.add(btnNew);

		JButton btnClear = new JButton("Clear");
		btnClear.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnClear_Call();
			}
		});
		btnClear.setBounds(391, 75, 113, 27);
		contentPane.add(btnClear);

		JButton btnLength = new JButton("Length");
		btnLength.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnLength_Call();
			}
		});
		btnLength.setBounds(391, 126, 113, 27);
		contentPane.add(btnLength);

		JButton btnIsEmpty = new JButton("isEmpty");
		btnIsEmpty.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnIsEmpty_Call();
			}
		});
		btnIsEmpty.setBounds(391, 177, 113, 27);
		contentPane.add(btnIsEmpty);

		JButton btnPeek = new JButton("Peek");
		btnPeek.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnPeek_Call();
			}
		});
		btnPeek.setBounds(391, 228, 113, 27);
		contentPane.add(btnPeek);

		JButton btnPush = new JButton("Push");
		btnPush.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnPush_Call();
			}
		});
		btnPush.setBounds(391, 279, 113, 27);
		contentPane.add(btnPush);

		JButton btnPop = new JButton("Pop");
		btnPop.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnPop_Call();
			}
		});
		btnPop.setBounds(391, 330, 113, 27);
		contentPane.add(btnPop);

		textShow = new JTextArea();
		textShow.setEditable(false);
		textShow.setLineWrap(true);
		textShow.setBounds(14, 46, 363, 140);
		contentPane.add(textShow);
		textShow.setColumns(10);

		JLabel lblNewLabel = new JLabel("Stack:");
		lblNewLabel.setBounds(14, 14, 87, 18);
		contentPane.add(lblNewLabel);

		panelOption = new JPanel();
		panelOption.setBorder(new LineBorder(new Color(0, 0, 0)));
		panelOption.setBounds(14, 200, 363, 172);
		contentPane.add(panelOption);
		panelOption.setLayout(null);

		comboBox = new JComboBox<Object>();
		comboBox.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent arg0) {
				rdbtnStack_Change();
			}
		});
		comboBox.setBounds(66, 11, 311, 24);
		contentPane.add(comboBox);

		// -------------------------------------
		panelNew = new JPanel();
		panelNew.setBorder(new LineBorder(new Color(0, 0, 0)));
		panelNew.setBounds(0, 0, 363, 172);
		panelNew.setLayout(null);

		textArea_New = new JTextArea();
		textArea_New.setBounds(15, 101, 334, 59);
		panelNew.add(textArea_New);

		JLabel lblValues_New = new JLabel("Values(split by comma):");
		lblValues_New.setBounds(14, 75, 257, 18);
		panelNew.add(lblValues_New);

		JButton btnNew_P = new JButton("New");
		btnNew_P.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnNew_P_Call();
			}
		});
		btnNew_P.setBounds(240, 40, 109, 27);
		panelNew.add(btnNew_P);

		rdbtnSequentialStack = new JRadioButton("Sequential Stack");
		rdbtnSequentialStack.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				textSize_New.setEnabled(true);
				textSize_New.setText("");
			}
		});
		rdbtnSequentialStack.setSelected(true);
		rdbtnSequentialStack.setBounds(32, 8, 157, 27);
		panelNew.add(rdbtnSequentialStack);

		rdbtnLinkStack = new JRadioButton("Link Stack");
		rdbtnLinkStack.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				textSize_New.setEnabled(false);
				textSize_New.setText("No need!");
			}
		});
		rdbtnLinkStack.setBounds(221, 8, 109, 27);
		panelNew.add(rdbtnLinkStack);

		ButtonGroup buttonGroup = new ButtonGroup();
		buttonGroup.add(rdbtnSequentialStack);
		buttonGroup.add(rdbtnLinkStack);

		JLabel lblSize_New = new JLabel("Size:");
		lblSize_New.setBounds(15, 44, 40, 18);
		panelNew.add(lblSize_New);

		textSize_New = new JTextField();
		textSize_New.setBounds(62, 43, 164, 24);
		panelNew.add(textSize_New);
		textSize_New.setColumns(10);

		// --------------------------------------------
		panelPush = new JPanel();
		panelPush.setBorder(new LineBorder(new Color(0, 0, 0)));
		panelPush.setLayout(null);
		panelPush.setBounds(0, 0, 363, 172);

		JLabel labelValue_Push = new JLabel("Value:");
		labelValue_Push.setBounds(14, 45, 56, 18);
		panelPush.add(labelValue_Push);

		textValue_Push = new JTextField();
		textValue_Push.setColumns(10);
		textValue_Push.setBounds(70, 42, 163, 24);
		panelPush.add(textValue_Push);

		JButton btnPush_P = new JButton("Push");
		btnPush_P.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnPush_P_Call();
			}
		});
		btnPush_P.setBounds(247, 41, 102, 27);
		panelPush.add(btnPush_P);

		labelResult_Push = new JLabel();
		labelResult_Push.setHorizontalAlignment(SwingConstants.CENTER);
		labelResult_Push.setBounds(14, 108, 335, 18);
		panelPush.add(labelResult_Push);

		// -----------------------------------
		panelShow = new JPanel();
		panelShow.setBorder(new LineBorder(new Color(0, 0, 0)));
		panelShow.setLayout(null);
		panelShow.setBounds(0, 0, 363, 172);

		labelMessage_Show = new JLabel("Empty Message!");
		labelMessage_Show.setHorizontalAlignment(SwingConstants.CENTER);
		labelMessage_Show.setBounds(14, 77, 335, 18);
		panelShow.add(labelMessage_Show);

		// -------------------------------------
		showMessage("Click New to Start!");
	}

	/**
	 * 清空栈按钮事件监听
	 */
	protected void btnClear_Call() {
		Object obj = comboBox.getSelectedItem();
		if (obj == null) {
			return;
		}
		String className = obj.getClass().getName();
		if ("SequentialStack".equals(className)) {
			SequentialStack s = (SequentialStack) obj;
			s.clear();
		} else {
			LinkStack l = (LinkStack) obj;
			l.clear();
		}
		showMessage("Cleared!");
		showStack();
	}

	/**
	 * 求栈长度按钮事件监听
	 */
	protected void btnLength_Call() {
		Object obj = comboBox.getSelectedItem();
		if (obj == null) {
			return;
		}
		String className = obj.getClass().getName();
		int length;
		if ("SequentialStack".equals(className)) {
			SequentialStack s = (SequentialStack) obj;
			length = s.length();
		} else {
			LinkStack l = (LinkStack) obj;
			length = l.length();
		}
		showMessage("Length of this stack is " + length + " !");
	}

	/**
	 * 判断栈是否为空事件监听
	 */
	protected void btnIsEmpty_Call() {
		Object obj = comboBox.getSelectedItem();
		if (obj == null) {
			return;
		}
		String className = obj.getClass().getName();
		boolean flag;
		if ("SequentialStack".equals(className)) {
			SequentialStack s = (SequentialStack) obj;
			flag = s.isEmpty();
		} else {
			LinkStack l = (LinkStack) obj;
			flag = l.isEmpty();
		}
		if (flag) {
			showMessage("This stack is empty!");
		} else {
			showMessage("This stack is not empty!");
		}
	}

	/**
	 * 取栈顶元素按钮事件监听
	 */
	protected void btnPeek_Call() {
		Object obj = comboBox.getSelectedItem();
		if (obj == null) {
			return;
		}
		String className = obj.getClass().getName();
		String value;
		if ("SequentialStack".equals(className)) {
			SequentialStack s = (SequentialStack) obj;
			if (s.peek() == null) {
				showMessage("This stack is empty!");
				return;
			} else {
				value = s.peek().toString();
			}
		} else {
			LinkStack l = (LinkStack) obj;
			if (l.peek() == null) {
				showMessage("This stack is empty!");
				return;
			} else {
				value = l.peek().toString();
			}
		}
		showMessage("Peek the element " + value + " ！");
	}

	/**
	 * 切换至入栈页面按钮事件监听
	 */
	protected void btnPush_Call() {
		if (comboBox.getSelectedItem() == null) {
			return;
		}
		switchPanel("Push");
	}

	/**
	 * 出栈按钮事件监听
	 */
	protected void btnPop_Call() {
		Object obj = comboBox.getSelectedItem();
		if (obj == null) {
			return;
		}
		String className = obj.getClass().getName();
		String value;
		if ("SequentialStack".equals(className)) {
			SequentialStack s = (SequentialStack) obj;
			try {
				value = s.pop().toString();
			} catch (Exception e) {
				showMessage(e.getMessage());
				return;
			}
		} else {
			LinkStack l = (LinkStack) obj;
			try {
				value = l.pop().toString();
			} catch (Exception e) {
				showMessage(e.getMessage());
				return;
			}
		}
		showMessage("Pop the element " + value + " !");
		showStack();
	}

	/**
	 * 新建按钮事件监听
	 */
	protected void btnNew_P_Call() {
		if (rdbtnSequentialStack.isSelected()) {
			if (textSize_New.getText().length() < 1) {
				showMessage("Input the size of the Sequential Stack!");
				return;
			}
			try {
				int size = Integer.parseInt(textSize_New.getText());
				SequentialStack s = new SequentialStack(size);
				if (textArea_New.getText().length() > 0) {
					String[] input = textArea_New.getText().split("[,，]");
					if (input.length > size) {
						showMessage("Size is too small!");
						return;
					} else {
						for (String data : input) {
							s.push(data);
						}
					}
				}
				comboBox.addItem(s);
				comboBox.setSelectedItem(s);
			} catch (Exception e) {
				showMessage(e.getMessage());
				return;
			}

		} else {
			LinkStack l;
			if (textArea_New.getText().length() > 0) {
				String[] input = textArea_New.getText().split("[,，]");
				l = new LinkStack(input);
			} else {
				l = new LinkStack();
			}
			comboBox.addItem(l);
			comboBox.setSelectedItem(l);
		}
		showMessage("Created a stack!");
	}

	/**
	 * 入栈按钮事件监听
	 */
	protected void btnPush_P_Call() {
		Object obj = comboBox.getSelectedItem();
		if (obj == null) {
			return;
		}
		String className = obj.getClass().getName();
		if (textValue_Push.getText().length() < 1) {
			labelResult_Push.setText("Input the value!");
			return;
		}
		String value = textValue_Push.getText();
		if ("SequentialStack".equals(className)) {
			SequentialStack s = (SequentialStack) obj;
			try {
				s.push(value);
			} catch (Exception e) {
				showMessage(e.getMessage());
				return;
			}
		} else {
			LinkStack l = (LinkStack) obj;
			l.push(value);
		}
		labelResult_Push.setText("Push an element!");
		textValue_Push.setText("");
		showStack();
	}

	/**
	 * 切换栈事件监听
	 */
	protected void rdbtnStack_Change() {
		showStack();
		showMessage("Choose an operation!");
	}

	/**
	 * 切换功能框
	 * 
	 * @param panelName
	 *            需要切换的功能框名
	 */
	private void switchPanel(String panelName) {
		// 去除功能框内原有的功能框
		panelOption.removeAll();
		// 切换对应的功能框
		switch (panelName) {
		case "New":
			textArea_New.setText("");
			textSize_New.setText("");
			rdbtnSequentialStack.setSelected(true);
			panelOption.add(panelNew);
			break;
		case "Push":
			textValue_Push.setText("");
			labelResult_Push.setText("");
			panelOption.add(panelPush);
		case "Show":
			panelOption.add(panelShow);
			break;
		}
		// 通知重绘
		panelOption.repaint();
	}

	/**
	 * 显示一个消息或结果
	 * 
	 * @param message
	 *            需要显示的信息
	 */
	private void showMessage(String message) {
		// 设置显示的信息
		labelMessage_Show.setText(message);
		// 切换到消息功能框
		switchPanel("Show");
	}

	/**
	 * 展示当前选中的栈
	 */
	private void showStack() {
		Object obj = comboBox.getSelectedItem();
		String className = obj.getClass().getName();
		if ("SequentialStack".equals(className)) {
			SequentialStack s = (SequentialStack) obj;
			textShow.setText(s.getString());
		} else {
			LinkStack l = (LinkStack) obj;
			textShow.setText(l.getString());
		}
	}

}
